package cn.pud.rpademo01.quartz;


import cn.pud.rpademo01.utils.EmailModel;
import cn.pud.rpademo01.utils.EmailUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import java.io.*;
import java.nio.file.Files;
import java.util.Date;
import java.util.UUID;

/**
 * @Author: Miyako
 * @Date: 2024-10-22-9:40
 * @Description:
 */
@Slf4j
public class EmailCheckJob implements Job {



    public EmailCheckJob() throws SchedulerException {
        //创建调度器工厂
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //通过调度器工厂创建调度器
        Scheduler scheduler = schedulerFactory.getScheduler();

        JobDetail jobDetail = JobBuilder.newJob(EmailCheckJob.class)
                //定义定时任务的名称和组 作为任务的唯一标识
                .withIdentity("EmailCheckJob" + UUID.randomUUID(),"email_check_jobs")
                .build();
        //定义任务触发的时间
        //当前时间
        long now = System.currentTimeMillis();
        long deviceCheckTime =  1 * 3 * 1000;
        //任务触发时间 = 当前时间 + 3s  任务会在3s以后执行
        Date triggerTime = new Date(now + deviceCheckTime);
        //触发器
        Trigger trigger = TriggerBuilder.newTrigger().startAt(triggerTime).build();
        //调度器scheduler  把 任务 jobDetail 和  触发器 trigger 进行绑定
        //调度器 scheduler 让任务 jobDetail 按照 时间 trigger 来触发
        scheduler.scheduleJob(jobDetail,trigger);
        //启动调用器
        scheduler.start();
    }


    /**
     * 定义任务内容
     * @param context
     * @throws JobExecutionException
     */
    @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            log.debug("开始检查邮箱");
            //通过
        EmailModel emailModel = SpringContextJobUtils.getBean("EmailModel", EmailModel.class);
        System.out.println(emailModel.getUsername());

        EmailUtil emailUtil = new EmailUtil(emailModel);
        Message[] messages = emailUtil.acceptNewEmail();
            try {
                // 遍历所有邮件
                MimeBodyPart part = findExcel(messages);
                if (part!=null)
                saveFile(part);
            }catch (Exception e) {
                throw new RuntimeException(e);
            }
    }

    //将Excel保存到本地
    private void saveFile(MimeBodyPart part) throws MessagingException, IOException {
        InputStream inputStream = part.getInputStream();
        String fileName = part.getFileName();
        File savePath = new File("D:\\Excel\\" + fileName);
        BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(savePath.toPath()));
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                //以字符的方式写入（输出到）硬盘
                bos.write(buffer, 0, bytesRead);
            }
            System.out.println("save to: " + savePath.getAbsolutePath());
    }

    private MimeBodyPart findExcel(Message[] messages) throws MessagingException, IOException {
        for (Message message : messages) {
            System.out.println("The New Email : " + message.getSubject());
            //判断邮件标题是否符合
            if (message.getSubject().startsWith("666"))
                //检测邮件内容是否含有附件,如果有附件(包含音视频文本文档都算)会返回MimeMultipart对象
                if (message.getContent() instanceof MimeMultipart) {
                    MimeMultipart multipart = (MimeMultipart) message.getContent();
                    //对筛选出的附件进行遍历
                    for (int i = 0; i < multipart.getCount(); i++) {
                        MimeBodyPart part = (MimeBodyPart) multipart.getBodyPart(i);
                        String fileName = part.getFileName();
                        if (fileName != null) {
                            // 去附件中筛选出Excel文件
                            if (fileName.endsWith(".xls") || fileName.endsWith(".xlsx")) {
                                System.out.println("Found Excel file: " + fileName);
                                return part;
                            }
                        }
                    }
                }
        }
        return null;
    }


}